home *** CD-ROM | disk | FTP | other *** search
- {*****************************************************************************
- TITLE: AXISLBL
- VERSION: 2.6
- FUNCTION: Axis labeling routine for use with a graphics window. This
- routine determines the appropriate spacing for tic-marks on the
- axis and then labels them.
- INPUTS: Graphics window file, extreme points for both axes, labels for
- both axes.
- OUTPUTS: Tic marks and labels for both axes.
- AUTHOR: M. Riebe (Modified by R. Carlson for Turbo Pascal)
- CHANGES: 6/20/85 RJC - New misfuncs version 1.6.
- 6/23/85 RJC - New misfuncs version 1.7
- 7/1/85 MTR: Cleaned up the tic marks at the beginning and end
- of axes.
- 9/24/85 RJC - New rcgraf version 1.2.
- 9/25/85 RJC - New misfuncs version 1.8.
- 10/26/85 RJC: New grafuncs version 2.2 and misfuncs version 2.0.
- 11/24/85 RJC: New misfuncs version 2.1.
- 12/10/85 MTR: Added some comments in the code and put tic marks
- on the top and right borders, moved axis labels so
- that unit multipliers didn't go offscreen.
- 1/05/86 RJC: New version of misfuncs (2.2).
- 1/17/86 RJC: New version of misfuncs (2.3).
- 2/04/86 RJC: Totally revised AXIS to make it more modular.
- Moved STR40 declaration to misfuncs.
- 6/13/86 RJC: New versions.
- 7/09/86 RJC: New versions.
- 8/26/86 RJC: New versions.
- 12/1/86 RJC: New versions.
- 5/31/90 RJC: Converted to Turbo Pascal.
- 2/15/91 RJC: Added CLRBOX procedure.
- *****************************************************************************}
-
- UNIT axislbl;
-
- INTERFACE
-
- USES IOFUNCS; {VERSION 1.1}
-
- PROCEDURE axis(LEFT,RIGHT,BOT,TOP:DOUBLE;
- LEFTSC,RIGHTSC,BOTSC,TOPSC:INTEGER;
- xlabel,ylabel:STR40);
- PROCEDURE CLRBOX(X0,Y0,X1,Y1:INTEGER; BOX:BOOLEAN);
- {This procedure clears the specified box and draws a box around it if
- BOX is true.}
-
- IMPLEMENTATION
-
- USES GRAPH,
- MATH; {VERSION 1.0}
-
- {*********************** PROCEDURE CLRBOX ******************************}
- PROCEDURE CLRBOX(X0,Y0,X1,Y1:INTEGER; BOX:BOOLEAN);
- {This procedure clears the specified box and draws a box around it if
- BOX is true.}
- BEGIN
- SETVIEWPORT(X0,Y0,X1,Y1,CLIPON); CLEARVIEWPORT;
- SETVIEWPORT(0,0,GETMAXX,GETMAXY,CLIPON);
- IF BOX THEN RECTANGLE(X0,Y0,X1,Y1);
- END;
-
- {******************************************************************************
- TITLE : PROCEDURE axis(LEFT,RIGHT,BOT,TOP:DOUBLE;
- LEFTSC,RIGHTSC,BOTSC,TOPSC:INTEGER;
- xlabel,ylabel:STR40);
- FUNCTION: Labels x and y axes for a plot contained in a given graphics window,
- and puts tic marks at appropriate spacings for >=5 labeled points
- per axis.
- AUTHOR : MTR/RJC
- INPUTS :BOTSC, TOPSC - bottom & top vertical plot boundaries
- LEFTSC, RIGHTSC - left & right horizontal plot boundaries
- NOTES : 1. The tick labels are in engineering notation except when the power
- is 3 in which case the numbers are writen out in full.
- 2. If a label does not fit on the screen then it is not placed on
- the screen at all.
- CHANGES : 12/10/85 MTR: Added comments in code and tic marks on top and right
- boundaries, moved axes labels so that multipliers fit
- on the screen.
- 2/04/86 RJC: Totally revised.
- 5/31/90 RJC: Translated to Turbo Pascal.
- ******************************************************************************}
- PROCEDURE AXIS;
-
- CONST MINTICKS=10; {minimum # of ticks, large and small}
-
- VAR
- MANT : DOUBLE; {engineering notation mantissa}
- MINXTICKS : INTEGER; {min # large ticks between labels}
- MULT : LONGINT; {loop counter}
- ST1, ST2 : STR80; {general usage strings}
- TICKSIZE : INTEGER; {length of ticks}
- UC : DOUBLE; {tick position in user coord.}
- XDEC, YDEC : INTEGER; {# digits to right of decimal to display}
- XINCR, YINCR : DOUBLE; {tick separation in user coordinates}
- XMAX, XMIN : DOUBLE; {max & min of x axis}
- XPOS, YPOS : INTEGER; {operating point coordinates}
- XPOWER, YPOWER : LONGINT; {power of 10 for x and y axes}
- YMAX, YMIN : DOUBLE; {max & min of y axis}
-
- PROCEDURE CREATSTRINGS(ST:STR40; POWER:LONGINT; VAR ST1,ST2:STR80);
- BEGIN
- ST1:=ST;
- IF POWER<>0 THEN BEGIN
- ST1:=CONCAT(ST1,' X10');
- STR(-1*POWER:5,ST2);
- WHILE ST2[1]=' ' DO DELETE(ST2,1,1);
- END {IF}
- ELSE ST2:='';
- END; {PROCEDURE CREATSTRINGS}
-
- FUNCTION XCOORDSC(UC:DOUBLE):INTEGER; BEGIN
- XCOORDSC:=ROUND( (UC-LEFT)/(RIGHT-LEFT) * (RIGHTSC-LEFTSC) + LEFTSC);
- END; {FUNCTION}
-
- FUNCTION YCOORDSC(UC:DOUBLE):INTEGER; BEGIN
- YCOORDSC:=ROUND( (UC-BOT)/(TOP-BOT) * (TOPSC-BOTSC) + BOTSC);
- END; {FUNCTION}
-
- BEGIN
- {determine extreme values}
- IF RIGHT>LEFT THEN BEGIN XMAX:=RIGHT; XMIN:=LEFT; END
- ELSE BEGIN XMAX:=LEFT; XMIN:=RIGHT; END;
- IF TOP>BOT THEN BEGIN YMAX:=TOP; YMIN:=BOT; END
- ELSE BEGIN YMAX:=BOT; YMIN:=TOP; END;
- {calculate appropriate power for both scales}
- IF ABS(LEFT)>ABS(RIGHT) THEN ENGNOT(LEFT,MANT,XPOWER)
- ELSE ENGNOT(RIGHT,MANT,XPOWER);
- IF ABS(TOP)>ABS(BOT) THEN ENGNOT(TOP,MANT,YPOWER)
- ELSE ENGNOT(BOT,MANT,YPOWER);
- IF XPOWER=3 THEN XPOWER:=0; IF YPOWER=3 THEN YPOWER:=0;
- {calculate tick spacing}
- XINCR:=CALCINCR(ABS(LEFT-RIGHT)/(MINTICKS-1));
- YINCR:=CALCINCR(ABS(TOP-BOT)/(MINTICKS-1));
- {calculate # of decimals to be output}
- XDEC:=NUMDEC(2*XINCR/PWROF10(XPOWER));
- YDEC:=NUMDEC(2*YINCR/PWROF10(YPOWER));
- {put overall x label on screen if possible}
- CREATSTRINGS(XLABEL,XPOWER,ST1,ST2);
- SETTEXTJUSTIFY(LEFTTEXT,BOTTOMTEXT);
- SETTEXTSTYLE(DEFAULTFONT,HORIZDIR,1); {horizontal text}
- XPOS:=((LEFTSC+RIGHTSC) DIV 2) - ROUND((LENGTH(ST1)+LENGTH(ST2))*4);
- YPOS:=BOTSC+32; {4 lines below x axis}
- IF (XPOS>=0) AND (YPOS<=GETMAXY) AND
- (XPOS+(LENGTH(ST1)+LENGTH(ST2))*9<=GETMAXX) THEN BEGIN
- MOVETO(XPOS,YPOS); OUTTEXT(ST1);
- XPOS:=GETX; YPOS:=GETY;
- OUTTEXTXY(XPOS,YPOS-8,ST2); {exponent}
- END; {IF}
- {put overall y label on screen if possible}
- CREATSTRINGS(YLABEL,YPOWER,ST1,ST2);
- SETTEXTJUSTIFY(LEFTTEXT,BOTTOMTEXT);
- SETTEXTSTYLE(DEFAULTFONT,VERTDIR,1); {vertical text}
- YPOS:=(BOTSC+TOPSC) DIV 2 + ROUND((LENGTH(ST1)+LENGTH(ST2))*4);
- XPOS:=LEFTSC-(YDEC+8)*8-8;
- IF XPOS<8 THEN XPOS:=8;
- IF (ST2<>'') AND (XPOS<16) THEN XPOS:=16;
- IF (YPOS<=BOTSC) AND (YPOS-(LENGTH(ST1)+LENGTH(ST2))*8>=TOPSC) THEN BEGIN
- MOVETO(XPOS,YPOS); OUTTEXT(ST1);
- XPOS:=GETX-8; YPOS:=GETY-LENGTH(ST1)*8;
- OUTTEXTXY(XPOS,YPOS,ST2);
- END; {IF}
- {calculate minimum # of large ticks between x axis labeled ticks}
- MINXTICKS:=1;
- IF ABS(XMAX)>ABS(XMIN) THEN STR(XMAX/PWROF10(XPOWER):XDEC+8:XDEC,ST1)
- ELSE STR(XMIN/PWROF10(XPOWER):XDEC+8:XDEC,ST1);
- WHILE ST1[1]=' ' DO DELETE(ST1,1,1);
- WHILE ((LENGTH(ST1)+2)*9) >
- (2*XINCR*ABS((RIGHTSC-LEFTSC)/(RIGHT-LEFT))*MINXTICKS)
- DO MINXTICKS:=MINXTICKS+1;
- {add x axis ticks and labels}
- FOR MULT:=ROUND((XMIN-XINCR)/XINCR) TO ROUND((XMAX+XINCR)/XINCR) DO BEGIN
- UC:=MULT*XINCR;
- SETTEXTJUSTIFY(CENTERTEXT,TOPTEXT);
- SETTEXTSTYLE(DEFAULTFONT,HORIZDIR,1);
- IF (UC<=XMAX) AND (UC>=XMIN) THEN BEGIN
- IF MULT MOD 2 = 0 THEN BEGIN {large tick}
- TICKSIZE:=6;
- IF (MULT DIV 2) MOD MINXTICKS = 0 THEN BEGIN {label the tick}
- STR(UC/PWROF10(XPOWER):XDEC+8:XDEC,ST1);
- WHILE ST1[1]=' ' DO DELETE(ST1,1,1);
- XPOS:=XCOORDSC(UC); YPOS:=BOTSC+4;
- IF (XPOS+LENGTH(ST1)*4)<GETMAXX THEN OUTTEXTXY(XPOS,YPOS,ST1);
- END; {IF}
- END {IF}
- ELSE TICKSIZE:=3; {small tick}
- XPOS:=XCOORDSC(UC);
- LINE(XPOS,BOTSC,XPOS,BOTSC-TICKSIZE);
- LINE(XPOS,TOPSC,XPOS,TOPSC+TICKSIZE);
- END; {IF}
- END; {FOR}
- {add y axis ticks and labels}
- FOR MULT:=ROUND((YMIN-YINCR)/YINCR) TO ROUND((YMAX+YINCR)/YINCR) DO BEGIN
- UC:=MULT*YINCR;
- SETTEXTSTYLE(DEFAULTFONT,HORIZDIR,1);
- SETTEXTJUSTIFY(RIGHTTEXT,CENTERTEXT);
- IF (UC<=YMAX) AND (UC>=YMIN) THEN BEGIN
- IF MULT MOD 2 = 0 THEN BEGIN {large tick}
- TICKSIZE:=6;
- STR(UC/PWROF10(YPOWER):YDEC+8:YDEC,ST1);
- WHILE ST1[1]=' ' DO DELETE(ST1,1,1);
- XPOS:=LEFTSC-8; YPOS:=YCOORDSC(UC);
- OUTTEXTXY(XPOS,YPOS,ST1);
- END {IF}
- ELSE TICKSIZE:=3; {small tick}
- YPOS:=YCOORDSC(UC);
- LINE(LEFTSC,YPOS,LEFTSC+TICKSIZE,YPOS);
- LINE(RIGHTSC,YPOS,RIGHTSC-TICKSIZE,YPOS);
- END; {IF}
- END; {FOR}
- END; {PROCEDURE AXIS}
-
- END.